#include "port_pwm.h"
#include "driver/ledc.h"
#include "port_config.h"

#define PWM_CH_MAX_NUM (2)
#define IS_PWM_CH_NUM(ch) ((ch) < PWM_CH_MAX_NUM)

static ledc_channel_config_t ledc_channel[PWM_CH_MAX_NUM] = {
    {
        .channel    = LEDC_CHANNEL_0,
        .duty       = 0,
        .gpio_num   = GPIO_PWM_CH0,
        .speed_mode = LEDC_HIGH_SPEED_MODE,
        .hpoint     = 0,
        .timer_sel  = LEDC_TIMER_0
    },
    {
        .channel    = LEDC_CHANNEL_1,
        .duty       = 0,
        .gpio_num   = GPIO_PWM_CH1,
        .speed_mode = LEDC_HIGH_SPEED_MODE,
        .hpoint     = 0,
        .timer_sel  = LEDC_TIMER_0
    }
};

void pwm_out_init(void)
{
    ledc_timer_config_t ledc_timer = 
    {
        .duty_resolution = LEDC_TIMER_10_BIT, // resolution of PWM duty
        .freq_hz = 10000,                      // frequency of PWM signal
        .speed_mode = LEDC_HIGH_SPEED_MODE,           // timer mode
        .timer_num = LEDC_TIMER_0,            // timer index
        .clk_cfg = LEDC_AUTO_CLK,              // Auto select the source clock
    };

    ledc_timer_config(&ledc_timer);

    for (uint8_t i = 0; i < PWM_CH_MAX_NUM; i++) 
    {
        ledc_channel_config(&ledc_channel[i]);
    }   
}

void pwm_out_set(uint8_t ch, uint32_t pwm)
{
    if(IS_PWM_CH_NUM(ch))
    {
        ledc_set_duty(ledc_channel[ch].speed_mode, ledc_channel[ch].channel, pwm);
        ledc_update_duty(ledc_channel[ch].speed_mode, ledc_channel[ch].channel);
    }
}